/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ApplicationLogic.modelPersistence;


import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.*;

import businessLogic.model.AbstractModel;

/**
 *
 * @author ProcariotaSoft
 */
public class DAOgenerico implements IDAOTEMPLATE {

    static IDAOTEMPLATE instance = null;
    private EntityManagerFactory emf;


    /*
     * Singleton sincronizado para evitar problemas de multi threading
     */
    public synchronized static IDAOTEMPLATE getInstance() {
        if (instance == null) {
            instance = new DAOgenerico();
        }
        return instance;
    }

    private DAOgenerico() 
    {
        emf = Persistence.createEntityManagerFactory("EmiFrameWorkPU");
           
    }

    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#createModel(modelo.AbstractModel)
	 */
    @Override
	public void createModel(AbstractModel c) throws Exception {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            System.out.println("Guardando Informacion");
            em.persist(c);
            tx.commit();
            System.out.println("Informacion guardada con exito!");
        } catch (Exception ex) {
        	ex.printStackTrace();
            if (tx.isActive()) {
                tx.rollback();
                
            }
            throw ex;
        }

    }

    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#deleteModel(int, java.lang.Class)
	 */
    @Override
	public void deleteModel(int id, Class tipo) throws Exception {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            System.out.println("Borrando Informacion");

            Object ABorrar = em.find(tipo, id);
            em.remove(ABorrar);
            tx.commit();
            System.out.println("Informacion borrada con exito!");
        } catch (Exception ex) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw ex;
        }

    }

    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#updateModel(modelo.AbstractModel)
	 */
    @Override
	public void updateModel(AbstractModel c) throws Exception {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            System.out.println("Modificando información");
            em.merge(c);
            tx.commit();
            System.out.println("Información modificada");
        } catch (Exception ex) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw ex;

        }
    }

    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#listModelByType(java.lang.String, int)
	 */
    @Override
	public List<AbstractModel> listModelByType(String tipo, int paging) {
        //TODO: fix paging
    	
    	int rowsPerPage = 10;
    	if (paging<=0) paging = 1;
    	int firstResult = (paging-1)*rowsPerPage;
        
    	
    	EntityManager em = emf.createEntityManager();
        
        Query q = em.createQuery("SELECT c FROM " + tipo + " c").setFirstResult(firstResult).setMaxResults(rowsPerPage);
        
        return q.getResultList();
    }
    
    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#getModelById(int, java.lang.Class)
	 */
    @Override
	public AbstractModel getModelById(int id, Class tipo) {

        EntityManager em = emf.createEntityManager();

        AbstractModel pp = (AbstractModel)em.find(tipo, id);

        return pp;

    }

    /* (non-Javadoc)
	 * @see persistencia.IDAOTEMPLATE#searchObject(java.lang.String)
	 */
    @Override
	public List<AbstractModel> searchObject(String SearchCriteria, int paging)
    {
    	if (paging<=0) paging = 1;
    	int rowsPerPage = 10;
    	int firstResult = (paging-1)*rowsPerPage; 
    	
    	EntityManager em = emf.createEntityManager();
         
         Query q = em.createQuery(SearchCriteria).setFirstResult(firstResult).setMaxResults(rowsPerPage);
                
         return q.getResultList();
    }
    




}
